//
// Created by chizuru on 2025/9/2.
//

#include "ConnectivityMonitor.h"
using std::function;
using std::thread;
using std::atomic_bool;
using std::condition_variable;
using std::mutex;
using namespace std::chrono;
using std::unique_lock;

ConnectivityMonitor::ConnectivityMonitor(function<bool()> checkFunc, function<void(bool)> observer, std::chrono::milliseconds interval)
    : checkFunc(move(checkFunc))
    , observer(move(observer))
    , interval(interval) {

}

ConnectivityMonitor::~ConnectivityMonitor() { stop(); }

void ConnectivityMonitor::start() {
    bool expected = false;
    if (!running.compare_exchange_strong(expected, true))
        return;
    worker = thread([this](){
        bool lastState = false;
        while (running) {
            bool ok = false;
            try {
                ok = checkFunc();
            } catch (...) {
                ok = false;
            }
            if (ok != lastState) {
                observer(ok);
                lastState = ok;
            }
            unique_lock lk(mtx);
            cv.wait_for(lk, interval, [this]{ return !running.load(); });
        }
    });
}
void ConnectivityMonitor::stop() {
    bool expected = true;
    if (!running.compare_exchange_strong(expected, false))
        return;
    cv.notify_all();
    if (worker.joinable())
        worker.join();
}